package com.jml.jdk8;


import java.util.function.BiFunction;
import java.util.function.Function;

/**
 * @author:jml
 * @date: 2019/7/24 0024 21:28
 * @description：compose和andThen   BiFuntion
 */
public class FunctionTest2 {

    public static void main(String[] args) {
        FunctionTest2 test = new FunctionTest2();

        int compute = test.compute(2, value -> value * 3, value -> value * value);
        System.out.println(compute);

        int compute2 = test.compute2(2, value -> value * 3, value -> value * value);
        System.out.println(compute2);

        int biFun = test.computer3(1, 2, (value1, value2) -> value1 + value2);
        System.out.println(biFun);

        int biFunAndThen = test.computer4(1, 2, (value1, value2) -> value1 + value2, value -> value * 3);
        System.out.println(biFunAndThen);

    }

    //function2就是 value * value  然后再把  value * value再作为function1的参数
    //function1就是 value * 3  ，value被替换后就是(value * value)*3 所以是12
    //先是2*2  然后是 4*3
    public  int compute(int a ,Function<Integer,Integer> function1, Function<Integer,Integer> function2){
        Function<Integer, Integer> compose = function1.compose(function2);
        return compose.apply(a);//.apply(a);

        //return function1.compose(function2).apply(a);
    }

    //先是执行function1的实现2*3然后把结果作为function2得参数，再实现function2，所以就是2*3的平方   就是36
    public  int compute2(int a ,Function<Integer,Integer> function1, Function<Integer,Integer> function2){
        return function1.andThen(function2).apply(a);
    }

    //先是执行before的apply实现方法，就是value * value  返回Function
    //然而该Function在之前就有定义就是value * 3，所以该Function的apply方法就是(value * value) *3
    //return (V v) -> apply(before.apply(v)); 第一个apply是调用者的实现方法，第二个apply是参数的apply方法

    /*default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
        Objects.requireNonNull(before);
        return (V v) -> apply(before.apply(v));
    }*/


    //先是执行调用者的apply实现方法，就是value * 3  返回Function
    //然而该Function在之前就有定义就是value * value，所以该Function的apply方法就是(value * 3)*(value *3)
    //显示执行调用者的apply方法，得到的结果作为参数给 方法中的参数
    /*default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
        Objects.requireNonNull(after);
        return (T t) -> after.apply(apply(t));
    }*/


    public int add(int a,int b){
        return a+b;
    }

    public int computer3(int a,int b, BiFunction<Integer,Integer,Integer> biFunction){
        return biFunction.apply(a,b);
    }
    //先执行调用者BiFunction的apply，在执行参数Function的apply参数是BiFunction的返回值
    public int computer4(int a,int b, BiFunction<Integer,Integer,Integer> biFunction,Function<Integer,Integer> fuction){
        BiFunction<Integer, Integer, Integer> biFunction1 = biFunction.andThen(fuction);
        System.out.println(biFunction1);
        return biFunction.andThen(fuction).apply(a,b);
    }
    //先执行调用者BiFunction的apply将两个参数转为一个结果，在执行参数的Function的apply实现参数是合二为一的结果值
    /*default <V> BiFunction<T, U, V> andThen(Function<? super R, ? extends V> after) {
        Objects.requireNonNull(after);
        return (T t, U u) -> after.apply(apply(t, u));
    }*/
}
